package com.xsir.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xsir.dto.RegisterForm;
import com.xsir.dto.UserInfo;
import com.xsir.entity.User;
import com.xsir.mapper.RoleMapper;
import com.xsir.mapper.UserMapper;
import com.xsir.service.IUserService;
import com.xsir.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author xsir
 * @date 2020/9/5
 * <p>
 * User表业务层接口实现类
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    private static final String DEFAULT_ALGORITHM = "md5";
    private static final String DEFAULT_PASSWORD = "123456";
    
    @Resource
    private UserMapper userMapper;
    @Resource
    private RoleMapper roleMapper;
    
    @Override
    public String login(String account, String password, Integer role) {
        User user;
        // 1、查询账号
        if (role == 0) {
            user = userMapper.selectOne(new QueryWrapper<User>().eq("account", account));
        } else if (role == 1) {
            user = userMapper.getOneAdmin(account);
        } else {
            throw new UnknownAccountException("账号不存在！");
        }
        if (null == user) {
            throw new UnknownAccountException("账号不存在！");
        }
        // 2、检验账号有效性
        if (user.getStatus() == 1) {
            throw new LockedAccountException("账号已被锁定！");
        }
        // 3、检验密码：把传入的密码进行盐值加密，和数据库中的密码比较
        password = new SimpleHash(DEFAULT_ALGORITHM, password, account).toString();
        if (!password.equals(user.getPassword())) {
            throw new AuthenticationException("密码错误！");
        }
        // 4、登录成功，生成token
        Map<String, Object> userInfo = new HashMap<>(8);
        List<String> roles = roleMapper.getRoles(account);
        userInfo.put("roles", roles);
        userInfo.put("uid", user.getId());
        userInfo.put("username", user.getUsername());
        userInfo.put("account", account);
        userInfo.put("avatar", user.getAvatar());
        // 设置密钥，用账号作为jwt密钥
        JwtUtil.encodedSecretKey(account);
        return JwtUtil.generate("xsir", userInfo);
    }
    
    @Override
    public String register(RegisterForm registerForm) {
        log.info(registerForm.toString());
        
        String email = registerForm.getEmail();
        String password = registerForm.getPassword();
        String username = registerForm.getUsername();
        String checkPass = registerForm.getCheckPass();
        
        // 1、检验用户名和密码
        if (StringUtils.isEmpty(username)) {
            throw new AuthenticationException("用户名不能为空！");
        }
        if (StringUtils.isEmpty(password) || StringUtils.isEmpty(checkPass)) {
            throw new AuthenticationException("密码不能为空！");
        }
        if (!Objects.equals(password, checkPass)) {
            throw new AuthenticationException("两次输入的密码不一致！");
        }
        
        // 3、检验用户名和邮箱
        User user = new User();
        // // 检验用户名是否已存在
        // if (null != userMapper.selectOne(new QueryWrapper<User>().eq("username", username))) {
        //     throw new AuthenticationException("用户名已存在！");
        // }
        // 检验邮箱
        if (null != userMapper.selectOne(new QueryWrapper<User>().eq("email", email))) {
            throw new AuthenticationException("邮箱已被注册！");
        }
        
        user.setAccount(email);
        user.setUsername(username);
        user.setEmail(email);
        // 4、对密码进行盐值加密
        password = new SimpleHash(DEFAULT_ALGORITHM, password, user.getAccount()).toString();
        user.setPassword(password);
        user.setCreateTime(LocalDateTime.now());
        // 5、添加注册用户
        userMapper.insertKey(user);
        // 分配角色
        roleMapper.assignTo(user.getId(), 1L);
        // 6、生成token
        Map<String, Object> userInfo = new HashMap<>(8);
        userInfo.put("roles", "user");
        userInfo.put("uid", user.getId());
        userInfo.put("username", username);
        userInfo.put("account", user.getAccount());
        userInfo.put("avatar", user.getAvatar());
        
        // 用账号作为jwt密钥
        JwtUtil.encodedSecretKey(user.getAccount());
        return JwtUtil.generate("xsir", userInfo);
    }
    
    @Override
    public UserInfo info(Long id) {
        SecurityUtils.getSubject().getPrincipal();
        User user = userMapper.selectById(id);
        return new UserInfo(user);
    }
    
    @Override
    public void resetPassword(String account, String password) {
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("account", account));
        if (user == null) {
            throw new UnknownAccountException("用户不存在！");
        }
        if (!user.getStatus().equals(0)) {
            throw new LockedAccountException("账号异常！");
        }
        password = new SimpleHash(DEFAULT_ALGORITHM, password, account).toString();
        user.setPassword(password);
    }
    
    @Override
    public void insertBatch(List<User> userList) {
        userList.forEach(user -> {
            // 设置默认密码、注册时间
            user.setPassword(new SimpleHash(DEFAULT_ALGORITHM, DEFAULT_PASSWORD, user.getAccount()).toString());
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
        });
        userMapper.insertBatch(userList);
    }
}
